package com.sky.task;

import com.alibaba.fastjson.JSONObject;
import com.sky.mapper.user.UserOrderMapper;
import com.sky.pojo.Orders;
import com.sky.properties.WeChatProperties;
import com.sky.service.user.UserOrderService;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 自定义定时任务，实现订单状态定时处理
 */
@Component
@Slf4j
public class OrderTask {
    @Autowired
    private UserOrderMapper orderMapper;
    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private UserOrderService orderService;


    @Scheduled(cron = "0 0/5 * * * ?")
    public void scanPayment() throws IOException {
        //逻辑：1.查询15分钟之前下单，订单状态为未支付的订单
        //获取当前时间-15分钟
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE,-15);
        Date before15Minute = calendar.getTime();
        List<Orders> ordersList = orderMapper.queryNeedCheckStatusOrOrders(Orders.PENDING_PAYMENT,before15Minute);
        if(CollectionUtils.isEmpty(ordersList)){
            log.info("没有需要处理的订单");
            return;
        }
        log.info("需要处理{}条订单",ordersList.size());
        //2.循环处理每个订单，去微信查询支付结果
        CloseableHttpClient payHttpClient = createPayHttpClient();
        for (Orders order : ordersList) {
            //获取客户端
            String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + order.getNumber() + "?mchid=" + weChatProperties.getMchid();
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("Accept","application/json");
            CloseableHttpResponse response = payHttpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            //404表示用户根本没有发起支付，订单取消掉
            if(statusCode == HttpStatus.SC_NOT_FOUND){
                log.info("用户没发起支付，订单取消");
                orderMapper.updateStatus(Orders.CANCELLED_ORDER,order.getNumber());
                continue;
            }
            //3.根据微信返回，处理结果，要么没有支付--订单取消，要么完成订单--订单完成
            String result = EntityUtils.toString(response.getEntity());
            log.info("调用微信接口请求返回:{}",result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String tradeState = (String) jsonObject.get("trade_state");
            //支付成功
            if ("SUCCESS".equals(tradeState)){
                log.info("用户已经完成支付");
                orderService.success(order.getNumber());
            }else{
                log.info("订单超过15分钟未支付，订单取消");
                orderMapper.updateStatus(Orders.CANCELLED_ORDER,order.getNumber());
            }
        }
        log.info("任务完成");
    }
    /**
     * 创建微信支付请求的HttpClient
     * @return
     * @throws UnsupportedEncodingException
     */
    private CloseableHttpClient createPayHttpClient() throws UnsupportedEncodingException {
        String privateKey = weChatProperties.getPrivateKey();
        String mchSerialNo = weChatProperties.getMchSerialNo();
        String mchId = weChatProperties.getMchid();
        String apiV3Key = weChatProperties.getApiV3Key();
        // 加载商户私钥（privateKey：私钥字符串）
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
        // 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3密钥）
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, merchantPrivateKey);
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(
                mchId, privateKeySigner);
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                wechatPay2Credentials, apiV3Key.getBytes("utf-8"));
        // 初始化httpClient
        return WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier))
                .build();
    }
}
